package com.xc.sys.controller;

import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSONObject;
import com.xc.common.object.*;
import com.xc.common.tool.Helper;
import com.xc.common.tool.PASSWORDUtil;
import com.xc.db.Tables;
import com.xc.db.tables.Paper;
import com.xc.db.tables.SysRole;
import com.xc.db.tables.SysUser;
import com.xc.db.tables.records.DateScoreRecord;
import com.xc.db.tables.records.PaperUserRecord;
import com.xc.sys.entity.SysDictEntity;
import com.xc.sys.entity.SysOrganizationEntity;
import com.xc.sys.entity.SysRoleEntity;
import com.xc.sys.entity.SysUserEntity;
import com.xc.sys.service.SysDictService;
import com.xc.sys.service.SysOrganizationService;
import com.xc.sys.service.SysRoleService;
import com.xc.sys.service.SysUserService;
import com.xc.sys.vo.SysUserVO;
import org.apache.commons.compress.utils.Lists;
import org.apache.commons.lang3.StringUtils;
import org.jooq.*;
import org.jooq.impl.DSL;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@RestController
@RequestMapping({ "/user" })
@CrossOrigin
public class SysUserController {
	@Autowired
	private DSLContext dsl;
	@Autowired
	private SysUserService sysUserService;
	@Autowired
	private SysRoleService sysRoleService;
    private Paper PAPERTB = Paper.PAPER.as("PAPERTB");
	@Autowired
	private SysOrganizationService sysOrganizationService;
	private SysUser USER = SysUser.SYS_USER.as("USER");
	private SysRole SYSROLETB = SysRole.SYS_ROLE.as("SYSROLETB");

	@Value("${weixin.appid}")
	private String appid;
	@Value("${weixin.secret}")
	private String secret;

	@RequestMapping({ "/getMeInfo" })
	private LayuiTableResponse<SysUserEntity> getMeInfo(HttpServletRequest request) {
		LayuiTableResponse<SysUserEntity> ltr = new LayuiTableResponse<>();
		HttpSession session = request.getSession();
		SysUserEntity me = (SysUserEntity) session.getAttribute("me");
		List<SysUserEntity> data = new ArrayList<>();
		JSONObject jobj = new JSONObject();
		jobj.put("name", me.getName());
		data.add(me);
		ltr.setData(data);
		return ltr;
	}

	@RequestMapping({ "/getList" })
	public LayuiTableResponse<SysUserVO> getList(HttpServletRequest request) {
		String ids = request.getParameter("ids");
		String execludeids = request.getParameter("execludeids");
		String roleCode = request.getParameter("roleCode");
		String orgId = request.getParameter("orgId");
		String paperId = request.getParameter("paperId");
		String name = request.getParameter("name");
		LayuiTableResponse<SysUserVO> ltr = new LayuiTableResponse<>();
		Condition cond = DSL.trueCondition();
		if (StringUtils.isNotEmpty(execludeids)) {
			cond = cond.and(USER.ID.notIn(Helper.str2integerArr(execludeids)));
		}
		if (StringUtils.isNotEmpty(ids)) {
			cond = USER.ID.in(Helper.covertArr2Ls(ids));
		}
		if (StringUtils.isNotEmpty(orgId)) {
			cond = USER.ORG_ID.eq(Integer.valueOf(orgId));
		}
		if (StringUtils.isNotEmpty(name)) {
			cond = USER.NAME.like("%" + name + "%");
		}
		if (StringUtils.isNotEmpty(paperId)) {
			cond = USER.ID.in(DSL.select(DSL.field("user_id")).from(Tables.PAPER_USER).where(DSL.field("paper_id").eq(Long.valueOf(paperId))).asField());
		}
		if(StringUtils.isNotEmpty(roleCode)) {
			cond = cond.and(DSL.or(USER.ROLE_CODE.eq(roleCode),USER.ROLE_CODE.contains(roleCode+","),USER.ROLE_CODE.contains("," + roleCode)));
		}
		
		String keywords = request.getParameter("keywords");
		if(StringUtils.isNotEmpty(keywords)) {
			cond = USER.NAME.like("%" + keywords + "%");
		}
		ltr.setMsg("没有数据");

		List<SysUserVO> list = sysUserService.selectVo(cond,USER.NAME.asc(), USER.CODE.asc());
		list = convertEntity2vo(list);
		ltr.setData(list);
		return ltr;
	}
	@CrossOrigin(origins = "*", allowedHeaders = {"*"}, methods = {RequestMethod.GET})
	@RequestMapping({ "/getPageList" })
	public LayuiTableResponse<SysUserVO> getPageList(HttpServletRequest request) {
		LayuiTableResponse<SysUserVO> ltr = new LayuiTableResponse<>();
		String spage = request.getParameter("page");
		String notPaperId = request.getParameter("notPaperId");
		String paperId = request.getParameter("paperId");
		String slimit = request.getParameter("limit");
		if(!StringUtils.isNumeric(spage)) {
			ltr.setCode(1);
			return ltr;
		}
		if(!StringUtils.isNumeric(slimit)) {
			ltr.setCode(1);
			return ltr;
		}
		int page = Integer.parseInt(spage);
		int limit = Integer.parseInt(slimit);
		String orgId = request.getParameter("orgId");
		String name = request.getParameter("name");
		String roleCode = request.getParameter("roleCode");
		String ids = request.getParameter("ids");
		String execludeids = request.getParameter("execludeids");
		Condition cond = USER.ID.isNotNull();
		if (StringUtils.isNotEmpty(execludeids)) {
			cond = cond.and(USER.ID.notIn(Helper.str2integerArr(execludeids)));
		}
		if (StringUtils.isNotEmpty(ids)) {
			cond = USER.ID.in(Helper.covertArr2Ls(ids));
		}
		if (StringUtils.isNotEmpty(notPaperId)) {
			cond = cond.and(DSL.notExists(DSL.select(Tables.PAPER_USER.USER_ID).from(Tables.PAPER_USER).where(DSL.field("paper_id").eq(Long.valueOf(notPaperId))
					.and(DSL.field("user_id").eq(USER.ID))
					)));
		}
		if (StringUtils.isNotEmpty(paperId)) {
			cond = cond.and(DSL.exists(DSL.select(Tables.PAPER_USER.USER_ID).from(Tables.PAPER_USER).where(DSL.field("paper_id").eq(Long.valueOf(paperId))
					.and(DSL.field("user_id").eq(USER.ID))
					)));
		}
		if (StringUtils.isNotEmpty(orgId)) {
			SysOrganizationEntity curnode = SysOrganizationService.getFromCaches(orgId);
			Condition cond1 = DSL.or(USER.NODE_ORG_ID.eq(Integer.valueOf(orgId)) , USER.NODE_ORG_ID.in(DSL.select(DSL.field("ID")).from(Tables.SYS_ORGANIZATION).where(DSL.field("CODE").startsWith(curnode.getCode()+".")).asField()));
			cond = cond.and(cond1);
		}
		if (StringUtils.isNotEmpty(name)) {
			cond = cond.and(DSL.or(USER.NAME.like("%"+name+"%"),USER.MOBILENO.like("%"+name+"%"),USER.WXID.eq(name)));
		}
		if(StringUtils.isNotEmpty(roleCode)) {
			cond = cond.and(DSL.or(USER.ROLE_CODE.eq(roleCode),USER.ROLE_CODE.contains(roleCode+","),USER.ROLE_CODE.contains(","+roleCode)));
		}
		String keywords = request.getParameter("keywords");
		if(StringUtils.isNotEmpty(keywords)) {
			cond = DSL.or(USER.NAME.like("%" + keywords + "%"),USER.MOBILENO.endsWith(keywords),USER.FULL_PINYIN.like("%"+ keywords + "%"),USER.INITIAL_LETTER.like("%"+ keywords + "%"));
		}
		cond = cond.and(USER.STATE.notEqual(-1));
		SortField<?>[] orderby = new SortField[]{USER.CREATE_TIME.asc(),USER.NAME.asc()};
		request.getSession().setAttribute("SysUserQueryCond", cond);
		request.getSession().setAttribute("SysUserOrderby", orderby);
		Long count = sysUserService.count(cond);
		ltr.setMsg("没有数据");
		PageInfo<SysUserEntity> pageInfo = new PageInfo<>(limit, page);
		Result<Record> r = sysUserService.select(cond, pageInfo, orderby);
		List<SysUserVO> list = r.into(SysUserVO.class);
		list = convertEntity2vo(list);
		ltr.setCount(count);
		ltr.setData(list);
		return ltr;
	}

	@PostMapping("forgotPwd")
	@ResponseBody
	@CrossOrigin
	public R forgotPwd(@RequestBody Map<String,Object> map){
		String phone = (String) map.get("phone");
		String ocode = (String) map.get("code");
		String password = (String) map.get("password");
		//判断验证码
		String code = Constant.yzmCache.getIfPresent(phone);
		System.out.println("code = " + code);
		if(code==null) {
			return R.error("验证码错误");
		}else {
			if(!ocode.equals(code)) {
				return R.error("验证码错误");
			}
		}
		//根据手机号查找用户
		List<SysUserEntity> select = sysUserService.select(USER.MOBILENO.eq(phone), USER.ID.asc());
		if (select.size()<=0){
			return R.error("该手机号暂未注册");
		}
		SysUserEntity sysUserEntity = select.get(0);
		sysUserEntity.setPassword(PASSWORDUtil.switchpassword(password));
		sysUserService.update(sysUserEntity);
		return R.success("找回密码成功");
	}

	@CrossOrigin(origins = "*", allowedHeaders = {"*"}, methods = {RequestMethod.GET})
	@RequestMapping({ "/getById" })
	public SysUserVO getById(Integer id) {
		SysUserVO user = SysUserService.getFrameCaches(id);
		setTxt(user);
		return user;
	}
	@RequestMapping({ "/getNamesByIds" })
	public String getNamesByIds(@RequestParam("ids[]") Integer[] ids) {
		List<SysUserEntity> list = sysUserService.select(USER.ID.in(ids),USER.NAME.asc(),USER.ID.asc());
		String name = list.stream().map(x->x.getName()).collect(Collectors.joining(","));
		return name;
	}
	@RequestMapping({ "/add" })
	@Transactional
	public ResponseEntity<SysUserEntity> add(SysUserEntity entity,HttpServletRequest request) {
		ResponseEntity<SysUserEntity> res = new ResponseEntity<>();
		SysUserEntity me = Helper.getMe(request);
		entity.setCreateTime(LocalDateTime.now());
		entity.setCreateUserId(me.getId());
		String password = PASSWORDUtil.switchpassword("123");
		entity.setPassword(password);
		Long count = sysUserService.count(USER.MOBILENO.eq(entity.getMobileno()));
		if (count == 0) {
			sysUserService.insert(entity);
		} else {
			res.setCode(1);
			res.setMsg("该账号已存在，请重新起一个");
		}
		res.setData(entity);
		return res;
	}
	@RequestMapping({ "/modify" })
	public ResponseEntity<SysUserEntity> modify(SysUserEntity entity) {
		Record record = sysUserService.getById(entity.getId());
		entity.setPassword(record.get(USER.PASSWORD));
		ResponseEntity<SysUserEntity> res = new ResponseEntity<>();
		if(StringUtils.isNotEmpty(entity.getCode())) {
			Long count = sysUserService.count(USER.CODE.eq(entity.getCode()).and(USER.STATE.eq(1))
					.and(USER.ID.notEqual(Integer.valueOf(entity.getId()))));
			if (count > 0) {
				res.setCode(1);
				res.setMsg("该账号已经被其他人占用，请重新填写");
				return res;
			}
		}
		if(StringUtils.isNotEmpty(entity.getMobileno())) {
			Long count = sysUserService.count(USER.MOBILENO.eq(entity.getMobileno()).and(USER.STATE.eq(1))
					.and(USER.ID.notEqual(Integer.valueOf(entity.getId()))));
			if (count > 0) {
				res.setCode(1);
				res.setMsg("该手机号已经被其他人占用，请重新填写");
				return res;
			}
		}
		
		sysUserService.update(entity);
		res.setData(entity);
		return res;
	}
	@CrossOrigin(origins = "*", allowedHeaders = {"*"}, methods = {RequestMethod.POST})
	@RequestMapping({ "/save" })
	public ResponseEntity<SysUserEntity> save(@RequestBody HashMap<String,String> params) {
		SysUserEntity entity = Helper.map2Bean(new SysUserEntity(), params);
		ResponseEntity<SysUserEntity> res = new ResponseEntity<>();
		res.setCode(0);
		SysUserEntity entity2 = null;
		if(StringUtils.isNotEmpty(entity.getId())) {
			entity2 = SysUserService.getFrameCaches(entity.getId());
		}
		if(entity2==null) {
			String password = PASSWORDUtil.switchpassword("123");
			entity.setPassword(password);
			Long count = 0l;
			if(entity.getCode()!=null&&!entity.getCode().isEmpty()) {
				count = sysUserService.count(USER.CODE.eq(entity.getCode()).and(USER.STATE.eq(1)) );
				if(count>0) {
					res.setCode(1);
					res.setMsg("该账号已经被其他人占用，请重新填写");
					return res;
				}
			}
			if(entity.getMobileno()!=null&&!entity.getMobileno().equals("")) {
				count = sysUserService.count(USER.MOBILENO.eq(entity.getMobileno()).and(USER.STATE.eq(1)));
				if(count>0) {
					res.setCode(1);
					res.setMsg("保存失败，该手机号已存在");
					return res;
				}
			}
			sysUserService.insert(entity);
			res.setData(entity);
			return res;
		}
		entity.setPassword(entity2.getPassword());
		if(StringUtils.isNotEmpty(entity.getCode())) {
			Long count = sysUserService.count(USER.CODE.eq(entity.getCode()).and(USER.ID.notEqual(Integer.valueOf(entity.getId()))).and(USER.STATE.eq(1)));
			if (count > 0) {
				res.setCode(1);
				res.setMsg("该账号已经被其他人占用，请重新填写");
				return res;
			}
		}
		if(StringUtils.isNotEmpty(entity.getMobileno())) {
			Long count = sysUserService.count(USER.MOBILENO.eq(entity.getMobileno()).and(USER.ID.notEqual(Integer.valueOf(entity.getId()))).and(USER.STATE.eq(1)));
			if (count > 0) {
				res.setCode(1);
				res.setMsg("该手机号已经被其他人占用，请重新填写");
				return res;
			}
		}
		sysUserService.update(entity);
		res.setData(entity);
		return res;
	}
	@CrossOrigin(origins = "*", allowedHeaders = {"*"}, methods = {RequestMethod.POST})
	@Transactional
	@RequestMapping({ "/changeOrg" })
	public ResponseEntity<SysUserEntity> changeOrg(@RequestBody HashMap<String,String> params) {
		String id = params.get("id");
		String orgId = params.get("orgId");
		String paperId = params.get("paperId");
		SysUserEntity entity = sysUserService.getEntityById(id);
		entity.setNodeOrgId(orgId);
		sysUserService.update(entity);
		ResponseEntity<SysUserEntity> res = new ResponseEntity<>();
	
		res.setCode(0);
		UpdateQuery<DateScoreRecord> q = dsl.updateQuery(Tables.DATE_SCORE);
		q.addConditions(Tables.DATE_SCORE.PAPER_ID.eq(Long.valueOf(paperId)));
		q.addConditions(Tables.DATE_SCORE.USER_ID.eq(Integer.valueOf(id)));
		q.addValue(Tables.DATE_SCORE.NODE_ORG_ID, Integer.valueOf(orgId));
		q.execute();
		
		res.setData(entity);
		return res;
	}

	@RequestMapping({ "/modifyPwd" })
	public LayuiTableResponse<SysUserEntity> modifyPwd(String pwd, String newPwd, HttpServletRequest request) {
		LayuiTableResponse<SysUserEntity> ltr = new LayuiTableResponse<>();
		SysUserEntity me = (SysUserEntity) request.getSession().getAttribute("me");
		if (me == null) {
			ltr.setCode(Integer.valueOf(-1));
			return ltr;
		}
		if (!me.getPassword().equals(pwd)) {
			ltr.setCode(Integer.valueOf(1));
		} else {
			me.setPassword(newPwd);
			sysUserService.update(me);
			SysUserService.userCache.invalidate(me.getId());
		}
		return ltr;
	}
	@PostMapping("/modifyPwdToJson")
	@CrossOrigin
	public JSONObject modifyPwdToJson(@RequestBody HashMap<String,String> params){
		JSONObject res = new JSONObject();
		String id = params.get("id");
		String oldPwd = params.get("oldPwd");
		String newPwd = params.get("newPwd");

		SysUserEntity user = sysUserService.getEntityById(id);

		if (user == null){
			res.put("code",1);
			res.put("msg","用户信息违法，不存在该用户");
			return res;
		}

		if (!user.getPassword().equals(PASSWORDUtil.switchpassword(oldPwd))){
			res.put("code",1);
			res.put("msg","原始密码错误");
			return res;
		}
		user.setPassword(PASSWORDUtil.switchpassword(newPwd));
		sysUserService.update(user);
		res.put("code",0);
		res.put("msg","修改密码成功");
		return res;
	}


	@RequestMapping({ "/resetPassword" })
	public LayuiTableResponse<SysUserEntity> resetPassword(String id) {
		SysUserEntity entity = sysUserService.getEntityById(id);
		String password = PASSWORDUtil.switchpassword("123");
		entity.setPassword(password);
		sysUserService.update(entity);
		LayuiTableResponse<SysUserEntity> ltr = new LayuiTableResponse<>();
		return ltr;
	}
	@RequestMapping({ "/assignPost" })
	public LayuiTableResponse<SysUserEntity> assignPost(@RequestBody HashMap<String,String> params) {
		String userId = params.get("userId");
		String roleCode = params.get("roleCode");
		String[] userIds = StringUtils.split(userId,",");
		for(String uid : userIds) {
			SysUserEntity userEntity = SysUserService.getFrameCaches(uid);
			if(StringUtils.isEmpty(userEntity.getRoleCode())) {
				userEntity.setRoleCode(roleCode);
			}else {
				userEntity.setRoleCode(userEntity.getRoleCode() + "," + roleCode);
			}
			sysUserService.update(userEntity);
		}
		
		LayuiTableResponse<SysUserEntity> ltr = new LayuiTableResponse<>();
		return ltr;
	}
	@RequestMapping({ "/deleteRole" })
	public LayuiTableResponse<SysUserEntity> deletePost(@RequestBody HashMap<String,String> params) {
		String userId = params.get("userId");
		String roleCode = params.get("roleCode");
		String[] userIds = StringUtils.split(userId,",");
		for(String uid : userIds) {
			SysUserEntity userEntity = SysUserService.getFrameCaches(uid);
			String psc = "," + userEntity.getRoleCode();
			psc = psc.replace("," + roleCode, "");
			if(psc.startsWith(",")) {
				psc = psc.substring(1);
			}
			userEntity.setRoleCode(psc);
			sysUserService.update(userEntity);
		}
		LayuiTableResponse<SysUserEntity> ltr = new LayuiTableResponse<>();
		return ltr;
	}
	@RequestMapping({ "/delete" })
	@Transactional
	public LayuiTableResponse<SysUserEntity> delete(@RequestParam("ids[]") Integer[] ids) {
		LayuiTableResponse<SysUserEntity> ltr = new LayuiTableResponse<>();
		for (Integer id : ids) {
			SysUserEntity u = SysUserService.getFrameCaches(id);
			u.setState(-1);
			sysUserService.update(u);
			//sysUserService.deleteById(id);
		}
		return ltr;
	}
	@RequestMapping({ "/clearAll" })
	@Transactional
	public ResponseEntity<SysUserEntity> clearAll() {
		ResponseEntity<SysUserEntity> res = new ResponseEntity<>();
		res.setCode(0);
		res.setMsg("已清空");
		sysUserService.deleteAll();
		SysUserService.idNumberCache.invalidateAll();
		SysUserService.userCache.invalidateAll();
		return res;
	}
	private List<SysUserVO> convertEntity2vo(List<SysUserVO> list) {
		List<SysUserVO> list2 = Lists.newArrayList();
		for (SysUserVO u : list) {
			SysUserVO vo = setTxt(u);
			list2.add(vo);
		}
		return list2;
	}

	private SysUserVO setTxt(SysUserVO vo) {
		SysOrganizationEntity org = SysOrganizationService.getFromCaches(vo.getOrgId());
		if(org==null) {
			if(vo.getOrgId()!=null) {
				sysOrganizationService.deleteById(Integer.valueOf(vo.getOrgId()));
				vo.setOrgName("");
			}
		}else {
			vo.setOrgName(org.getShortName()==null?(org.getName()==null?"":org.getName()):org.getShortName());
		}
		vo.setFullOrgName((vo==null||vo.getNodeOrgId()==null)?"":SysOrganizationService.getDetailOrgName(vo.getNodeOrgId()));
		SysOrganizationEntity branch = SysOrganizationService.getFromCaches(vo.getNodeOrgId());
		vo.setNodeOrgName(branch==null?"":branch.getShortName());
		if(StringUtils.isNotEmpty(vo.getRoleCode())) {
			String[] postIds = StringUtils.split(vo.getRoleCode(),",");
			List<SysRoleEntity> roles = sysRoleService.select(SYSROLETB.CODE.in(postIds), SYSROLETB.ORDERNO.asc());
			String roleNames = roles.stream().map(x -> x.getName()).collect(Collectors.joining(","));
			vo.setRoleName(roleNames);
		}
		
		SysDictEntity dict = SysDictService.getFromCaches("sex,"+vo.getGender());
		vo.setGenderTxt(dict==null?"":dict.getName());
		dict = SysDictService.getFromCaches("staff-type,"+vo.getStaffType());
		vo.setStaffTypeTxt(dict==null?"":dict.getName());
		SysUserVO user = SysUserService.getFrameCaches(vo.getCreateUserId());
		vo.setCreateUserName(user==null?"":user.getName());
		return vo;
	}

	/**
	 * 根据openid登录
	 * @param openId
	 * @return
	 */
	@CrossOrigin
	@PostMapping("/LoginByOpenId")
	public R loginByOpenId(@RequestBody String openId){
		List<SysUserEntity> select = sysUserService.select(USER.WXID.eq(openId), USER.ID.asc());
		if (select.size()<=0){
			return R.error("该微信号暂未绑定账号，请先注册或登录绑定");
		}
		SysUserEntity entityById = select.get(0);
		SysOrganizationEntity org = sysOrganizationService.getTopOrg(Integer.valueOf(entityById.getNodeOrgId()));
		SysOrganizationEntity store = SysOrganizationService.getFromCaches(entityById.getNodeOrgId());
		Map<String,Object> map = new HashMap<>();
		map.put("user",entityById);
		map.put("org",org);
		map.put("store",store);
		map.put("shortOrgName",StringUtils.isEmpty(store.getShortName()) ? store.getName() : store.getShortName());
		return R.success(map,"成功.");
	}

	@CrossOrigin(origins = "*", allowedHeaders = {"*"}, methods = {RequestMethod.GET})
	@RequestMapping({ "/getUserInfo" })
	public R getUserInfo(String id) {
		SysUserEntity entityById = sysUserService.getEntityById(id);
		if (entityById==null){
			return R.error("获取用户信息失败");
		}
		SysOrganizationEntity org = sysOrganizationService.getTopOrg(Integer.valueOf(entityById.getNodeOrgId()));
		SysOrganizationEntity store = SysOrganizationService.getFromCaches(entityById.getNodeOrgId());
		Map<String,Object> map = new HashMap<>();
		map.put("user",entityById);
		map.put("org",org);
		map.put("store",store);
		map.put("shortOrgName",StringUtils.isEmpty(store.getShortName()) ? store.getName() : store.getShortName());
		return R.success(map,"成功.");
	}
}
